package com.xbongbong.workorder.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.parent.explain.FormDataUpdateGetExplainHandler;
import com.xbongbong.paas.help.OwnerAndCoUserHelp;
import com.xbongbong.paas.lowcode.LowCodeConfigService;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateGetVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.abstracts.AbstractEditPageRenderService;
import com.xbongbong.parent.explain.FormDataAddFormExplainHandlerName;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormOwnerUniqueEnum;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.lowcodeconfig.pojo.dto.LowCodeConfigGetDTO;
import com.xbongbong.pro.lowcodeconfig.pojo.vo.LowCodeConfigGetVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFlowUserEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.UpdateDataTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.workorder.explain.WorkOrderExplainHandle;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/02/08 9:41
 */
@Service("workOrderEditPageRenderServiceImpl")
public class WorkOrderEditPageRenderServiceImpl extends AbstractEditPageRenderService<WorkOrderFormEntity, WorkOrderEntity> {

    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private OwnerAndCoUserHelp ownerAndCoUserHelp;
    @Resource
    private FormDataAddFormExplainHandlerName formDataAddFormExplainHandlerName;
    @Resource
    private FormDataUpdateGetExplainHandler formDataUpdateGetExplainHandler;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private WorkOrderFlowUserService workOrderFlowUserService;
    @Resource
    private WorkOrderExplainHandle workOrderExplainHandle;
    @Resource
    private LowCodeConfigService lowCodeConfigService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private RichTextService richTextService;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.WORK_ORDER.getCode());
    }

    @Override
    public void isApprovedEdit(FormDataUpdateGetDTO formDataUpdateGetDTO, WorkOrderEntity dataEntity, WorkOrderFormEntity formEntity) throws XbbException {
        boolean fromCopy = Objects.nonNull(formDataUpdateGetDTO.getSaasSpecialParamPojo()) && Objects.equals(formDataUpdateGetDTO.getSaasSpecialParamPojo().getFromCopy(), BasicConstant.ONE);

        workflowFormDataOperationService.isApprovedEdit(fromCopy, formEntity.getAppId(), formEntity.getMenuId(), formEntity.getId(), formEntity.getCorpid(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(), dataEntity.getFlowStatus(), formDataUpdateGetDTO.getLoginUser());
    }

    @Override
    public WorkOrderEntity getData(FormDataUpdateGetDTO formDataUpdateGetDTO) throws XbbException{
        String corpid = formDataUpdateGetDTO.getCorpid();
        Integer businessType = formDataUpdateGetDTO.getBusinessType();
        Long dataId = formDataUpdateGetDTO.getDataId();
        WorkOrderEntity paasFormDataEntityExt = workOrderModel.getByKey(dataId, corpid);
        if (paasFormDataEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        richTextService.addRichTextByDataId(dataId, corpid, formDataUpdateGetDTO.getFormId(), businessType, formDataUpdateGetDTO.getSaasMark(), paasFormDataEntityExt.getDel(), paasFormDataEntityExt.getData());
        if (Objects.equals(paasFormDataEntityExt.getDel(), DelEnum.DELETE.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        if (FlowStatusEnum.inApproval(paasFormDataEntityExt.getFlowStatus()) && !Objects.equals(businessType, XbbRefTypeEnum.DISTRIBUTOR_ACCOUNT.getCode())) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200020);
        }
        return paasFormDataEntityExt;
    }

    @Override
    public LowCodeConfigGetVO getLowCodeConfig(LowCodeConfigGetDTO lowCodeConfigGetDTO) throws XbbException {
        return  lowCodeConfigService.get(lowCodeConfigGetDTO);
    }

    @Override
    public WorkOrderFormEntity getForm(FormDataUpdateGetDTO formDataUpdateGetDTO) throws XbbException {
        return workOrderFormModel.getByKey(formDataUpdateGetDTO.getFormId(), formDataUpdateGetDTO.getCorpid());
    }

    @Override
    public List<FieldAttrEntity> getExplain(WorkOrderFormEntity dataEntity, String corpid) throws XbbException {
        WorkOrderExplainEntityExt paasFormExplainEntity = workOrderExplainModel.getByFormId(dataEntity.getId(), corpid);
        if ( paasFormExplainEntity == null ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        //根据套餐判断负责人属性
        Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
        boolean ultimateTag = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
        if(!ultimateTag && FormOwnerUniqueEnum.getDefaultBusinessList().contains(businessType)){
            //只有旗舰版支持负责人唯一设置，其他版本拿默认设置
            FormOwnerUniqueEnum formOwnerUniqueEnum = FormOwnerUniqueEnum.getFormOwnerUniqueByBus(businessType);
            Integer multiple = formOwnerUniqueEnum.getValue();
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                if(Objects.equals(fieldAttrEntity.getAttr(),FieldTypeEnum.OWNERID.getAlias())){
                    fieldAttrEntity.setMultiple(multiple);
                }
            }
        }
        return explainList;
    }

    @Override
    public HandlerExplainVO handleExplain(FormDataUpdateGetDTO formDataUpdateGetDTO, Map<String, UserEntity> userMap, WorkOrderEntity paasFormDataEntity, List<FieldAttrEntity> explainList, WorkOrderFormEntity form) throws XbbException {
        // ---- 获取用户和部门容器start
        UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
        BeanUtil.copyProperties(formDataUpdateGetDTO, userAndDepartmentGetDTO);
        userAndDepartmentGetDTO.setExplainList(explainList);
//            UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO);
//            Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
//            Map<String, DepartmentEntity> departmentMap = userAndDepartmentGetVO.getDepartmentMap();

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataUpdateGetDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(explainList);
        PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
        BeanUtil.copyProperties(form, paasFormEntityExt);
        paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
        handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);

        // 获取协同人和负责人
        ownerAndCoUserHelp.getOwnerIdAndCoUserId(handlerExplainDTO, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(), paasFormDataEntity, userMap, DelEnum.NORMAL.getDel());
        List<String> coUserIds = handlerExplainDTO.getCoUserId();
        HandlerExplainVO handlerExplainVO;
        boolean fromCopy = Objects.nonNull(formDataUpdateGetDTO.getSaasSpecialParamPojo()) && Objects.equals(formDataUpdateGetDTO.getSaasSpecialParamPojo().getFromCopy(), BasicConstant.ONE);

        if (fromCopy) {
            handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
        } else {
            handlerExplainVO = formDataUpdateGetExplainHandler.handleExplain(handlerExplainDTO);
        }
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        // 业务层字段解释处理
        businessHandleExplain(formDataUpdateGetDTO, handlerExplainVO.getHeadList(), form, paasFormDataEntity);
        handlerExplainVO.setOwnerId(handlerExplainDTO.getOwnerId());
        handlerExplainVO.setCoUserId(coUserIds);
        return handlerExplainVO;
    }

    @Override
    public ParseSingleRowDataVO formatData(FormDataUpdateGetDTO formDataUpdateGetDTO, HandlerExplainVO handlerExplainVO, WorkOrderEntity dataEntity) throws XbbException {
        Long dataId = dataEntity.getId();
        String corpid = formDataUpdateGetDTO.getCorpid();
        JSONObject data = dataEntity.getData();

        SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
        BeanUtil.copyProperties(formDataUpdateGetDTO, saasAnalysisDataDTO);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByList(handlerExplainVO.getHeadList());
        saasAnalysisDataDTO.setExplainMap(explainMap);
        // saas特殊格式转换
        workOrderModel.formatData(saasAnalysisDataDTO, dataEntity.getData());
        workOrderModel.formatProduct4Show2(dataId, corpid, data, UpdateDataTypeEnum.UPDATE);

        data.put(FieldTypeEnum.OWNERID.getAlias(), handlerExplainVO.getOwnerId());
        data.put(FieldTypeEnum.COUSERID.getAlias(), handlerExplainVO.getCoUserId());
        data.put(FieldTypeEnum.DEPARTMENTID.getAlias(), dataEntity.getDepartmentId());
        data.put(FieldTypeEnum.SERIALNO.getAlias(), dataEntity.getSerialNo());
        // 解析数据信息
        ParseSingleRowDataVO parseSingleRowDataVO = parseSingleRowData(formDataUpdateGetDTO, data, explainMap, handlerExplainVO.getUserMap(), handlerExplainVO.getDepartmentMap());
        // 模板数据
        parseSingleRowDataVO.getResult().put(FieldTypeEnum.TEMPLATE.getAlias(), dataEntity.getFormId());
        dataEntity.setData(parseSingleRowDataVO.getResult());
        return parseSingleRowDataVO;
    }

    @Override
    public void businessHandleExplain(FormDataUpdateGetDTO formDataUpdateGetDTO, List<FieldAttrEntity> list, WorkOrderFormEntity form, WorkOrderEntity dataEntity) throws XbbException {
        boolean fromCopy = Objects.nonNull(formDataUpdateGetDTO.getSaasSpecialParamPojo()) && Objects.equals(formDataUpdateGetDTO.getSaasSpecialParamPojo().getFromCopy(), BasicConstant.ONE);

        String corpid = formDataUpdateGetDTO.getCorpid();
        Long dataId = dataEntity.getId();
        WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(form.getTemplateId(), corpid);
        //工单如果是自由流程，负责人字段显示并必填，指定流程不显示
        boolean isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);

        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FieldAttrEntity fieldAttrEntity : list) {
            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);

            if (!isFree) {
                //指定流程。设置负责人不可见
                if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.USER.getType())
                        && Objects.equals(WorkOrderEnum.MANAGER_ID.getAttr(), fieldAttrEntity.getAttr())) {
                    fieldAttrEntity.setVisible(0);
                }
            } else {
                if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.USER.getType()) && fieldAttrEntity.getAttr().equals(WorkOrderEnum.MANAGER_ID.getAttr()) && !fromCopy) {
                    fieldAttrEntity.setEditable(0);
                    WorkOrderFlowUserEntity workOrderFlowUserEntity = workOrderFlowUserService.getMainUser(dataId, corpid);
                    if (Objects.nonNull(workOrderFlowUserEntity)) {
                        dataEntity.getData().put(fieldAttrEntity.getAttr(),workOrderFlowUserEntity.getUserId());
                    }
                }
            }
        }
        // 编辑时saas字段显示特殊逻辑
        FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
        BeanUtil.copyProperties(formDataUpdateGetDTO, formatExplainDTO);
        formatExplainDTO.setExplainList(list);
        formatExplainDTO.setDataEntity(dataEntity);

        workOrderModel.formatUpdateExplain(formatExplainDTO, dataEntity.getData());

        workOrderExplainHandle.setTemplate(list, formDataUpdateGetDTO.getLoginUser(), form);

    }

    @Override
    public void handelSaasSpecialUpdate(List<FieldAttrEntity> explainList, Integer businessType, WorkOrderEntity formDataEntityExt, boolean formCopy, Integer distributorMark) {

    }

    @Override
    public void formatSaasAttrToReturn(FormDataUpdateGetDTO formDataUpdateGetDTO, FormDataUpdateGetVO formDataUpdateGetVO, WorkOrderFormEntity form, WorkOrderEntity dataEntity) throws XbbException {
        PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
        BeanUtil.copyProperties(form, paasFormEntityExt);
        paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formDataUpdateGetVO.setPaasFormEntity(paasFormEntityExt);
        formDataUpdateGetVO.setData(dataEntity);
    }
}
